﻿using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;
using System.Security.Cryptography;
using Microsoft.Extensions.Configuration;
using System.Text;

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class ValidateTimestampAndSignatureAttribute : Attribute, IActionFilter
{
    private string _requiredApiKey;
    private string SecretKey = "";
    private IConfiguration _configuration;

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // 在这里可以执行操作后的逻辑
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        // 在这里执行操作前的逻辑

        // 从请求头中获取时间戳和签名
        var timestampHeader = context.HttpContext.Request.Headers["timestamp"];
        var signHeader = context.HttpContext.Request.Headers["sign"];

        if (string.IsNullOrEmpty(timestampHeader) || string.IsNullOrEmpty(signHeader))
        {
            context.Result = new JsonResult(new { message = "Missing timestamp or signature" })
            {
                StatusCode = 401
            };
            return;
        }

        if (!ValidateTimestampAndSignature(timestampHeader, signHeader,context))
        {
            context.Result = new JsonResult(new { message = "Invalid timestamp or signature" })
            {
                StatusCode = 401
            };
            return;
        }
    }

    private bool ValidateTimestampAndSignature(string timestampHeader, string signHeader, ActionExecutingContext context)
    {
        if (long.TryParse(timestampHeader, out long timestamp) && !string.IsNullOrEmpty(signHeader))
        {
            // 验证时间戳以防止重放攻击（例如，在某个时间窗口内）
            if (Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - timestamp) > 3000)
            {
                return false;
            }

            // 计算签名
            var calculatedSign = CalculateSignature(timestamp,context);

            // 将计算得到的签名与接收到的签名进行比较
            return calculatedSign == signHeader.ToLower();
        }

        return false;
    }

    private string CalculateSignature(long timestamp, ActionExecutingContext context)
    {
        // 通过属性注入获取 IConfiguration
        _configuration = (IConfiguration)context.HttpContext.RequestServices.GetService(typeof(IConfiguration));

        // 通过 IConfiguration 读取配置文件中的 API 密钥
        SecretKey = _configuration["APIConfig:ValidApiKey"];
        // 构造要进行MD5计算的字符串
        var concatenatedString = $"{timestamp}-{SecretKey}";

        // 计算第一次MD5哈希
        using (var md5 = MD5.Create())
        {
            var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(concatenatedString));

            // 将字节数组转换为十六进制字符串
            var firstHash = BitConverter.ToString(hash).Replace("-", "").ToLower();

            // 进行第二次MD5哈希
            var secondHash = md5.ComputeHash(Encoding.UTF8.GetBytes(firstHash));

            // 将第二次MD5哈希的字节数组转换为十六进制字符串
            return BitConverter.ToString(secondHash).Replace("-", "").ToLower();
        }
    }
}

